package com.lx.demo.b.utils;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * Created by lanyxp on 2020/6/30
 * 获取zookeeper节点信息返回生成雪花算法的workId
 */
@Slf4j
@Component
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class IdWorkGetUtil {
    private static final String BASE_PATH = "/worker-id/com.lx-project";

    public static long getSonrkInt(String zkServers, int dataCenter, String serverName) {
        CuratorFramework curatorFrameworkClient = null;
        try {
            if (zkServers.contains("//")) {
                zkServers = zkServers.substring(zkServers.indexOf("//") + 2);
            }
            if (zkServers.indexOf('?') < zkServers.indexOf('=')) {
                zkServers = zkServers.replace(zkServers.substring(zkServers.indexOf('?', zkServers.indexOf('=') + 1)), ",");
            }
            curatorFrameworkClient = CuratorFrameworkFactory.builder().connectString(zkServers).connectionTimeoutMs(20000).sessionTimeoutMs(60000).retryPolicy(new ExponentialBackoffRetry(5000, 3)).build();
            curatorFrameworkClient.start();
            String dataString = "{service: " + serverName + ", ip: " + InetAddress.getLocalHost().getHostAddress() + "}";
            log.debug("Service Info:{}", dataString);
            final byte[] data = dataString.getBytes(StandardCharsets.UTF_8);
            curatorFrameworkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(BASE_PATH + "/" + dataCenter, data);
            List<String> childrs = curatorFrameworkClient.getChildren().forPath(BASE_PATH);
            Integer workId = Integer.valueOf(childrs.get(0));
            log.info("Get Zookeeper Node Information is:{}", workId);
            return workId & 31;
        } catch (Exception e) {
            log.error(" Zookeeper Address acquisition exception:{}", e);
            throw new IllegalArgumentException("The value of ZK is abnormal");
        } finally {
            if (curatorFrameworkClient != null) {
                curatorFrameworkClient.close();
            }
        }
    }

    /****
     *
     * @param data
     * @return
     */
    public static int checksum(String data) {
        if (data == null || data.length() != 20) {
            throw new IllegalArgumentException("checksum failed for string lenth must be 20");
        }
        int sum = 0;
        for (int i = 0; i < 20; i++) {
            int v = data.charAt(i) - 0x30;
            if (i % 2 == 0) {
                sum += v;
            } else {
                sum += 2 * v % 9;
            }
        }
        return (10 - sum % 10) % 10;
    }
}
